#ifndef __PROCESS_POOL_HPP__
#define __PROCESS_POOL_HPP__

#include<iostream>
#include<string>
#include<vector>
#include<cstdlib>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<functional>
#include"Task.hpp"
#include"Channel.hpp"

using work_t = std::function<void()>;

enum
{
    OK=0,
    UsageError,
    PipeError,
    ForkError
    
};

class ProcessPool
{
    public:
    ProcessPool(int n,work_t w):processnum(n),work(w)
    {

    }
    int InitProcessPool()
    {
        for(int i=0;i<processnum;i++)
        {
            int pipefd[2]={0};
            int n=pipe(pipefd);
            if(n<0)
            {
                return PipeError;
            }

            pid_t id=fork();
            if(id<0)
            {
                return ForkError;
            }

            if(id==0)
            {
                std::cout<<getpid()<<",child close history fd: ";
                for(auto &c:channels)
                {
                    std::cout<<c.wFd()<<"";
                    c.Close();
                }
                std::cout<<"over"<<std::endl;

                ::close(pipefd[1]);

                std::cout<<"debug:"<<pipefd[0]<<std::endl;
                dup2(pipefd[0], 0);
                work();
                ::exit(0);
            }
                ::close(pipefd[0]);
                channels.emplace_back(pipefd[1],id);
        }
        return OK;
        
    }

    void DispatchTask()
    {
        int who=0;
        int num=20;
        while(num--)
        {
            int task=tm.SelectTask();
            Channel &curr=channels[who++];
            who%=channels.size();

            std::cout<<"#############"<<std::endl;
            std::cout<<"send"<<task<<"to"<<curr.Name<<"，任务还剩："<<num<<std::endl;
            std::cout<<"#############"<<std::endl;

            curr.Send(task);
            sleep(1);
        }

        void CleanProcessPool()
        {
            for(auto &c::channels)
            {
                c.close();
                pid_t rid=::waitpid(c.Id(),nullptr,0);
                if(rid>0)
                {
                    std::cout<<"child"<<rid<<"wait ... succerss"<<std::endl;
                }
            }
        }

        void DebugPrint()
        {
            for(anto &c : channels)
            {
                std::cout<<c.Name()<<std::endl;
            }
        }
    }
private:
    std::vector<Channel> channels;
    int processnum;
    work_t work;
};

#endif
